<?php

namespace Pinenut\Model;

/**
 * Связь
 * 
 * @author kosh
 */
class Reference extends Embedded {
	
	// идентификатор
	public $_ref;
	
	
	// обратная связь, если есть, если не нашли - надо получать
	protected $_backReference;
	
	/** 
	 * Контейнер
	 * @var \Pinenut\Model\ReferenceContainer 
	 */
	public $_parent;
	
	static function fields() {
		return array_merge(parent::fields(), array(
				'_ref'=>static::ID,
		));
	}
	
	/**
	 * @return \Pinenut\Model
	 */
	function getReferredModel($empty = false) {
		$class = $this->_parent->getReferredClass();
		if ($empty) {
			// TODO: инициализация пустышки с идентификатором
		} else {
			return $class::find($this->_ref, true);
		}
	}
	
	/**
	 * Возвращаем контейнер для связи
	 * @return \Pinenut\Model\ReferenceContainer
	 */
	function getBackReferenceContainer() {
		// действуем в лоб - получаем сущность, получаем из неё нужную связь
		return $this->getReferredModel()
					->getValue($this->_parent->getReferredField());
	}
	
	function setBackReference(Reference $reference) {
		$this->_backReference = $reference;
	}
	
	function getBackReference() {
		
		if ($this->_parent->getReferredField() === null) 
			return null;
		
		if (null === $this->_backReference) {
			$this->_backReference = $this->getBackReferenceContainer()
				->getReference($this->getModel()->_id);
		} 
		
		return $this->_backReference;
	}
	
	
	/**
	 * Так же как файндер - делаем апдейтер, чтобы он при его вызове относительно вложенного документа, 
	 * уже делал поправку и обновлял поля в этом вложенном документе
	 * 
	 * 
	 * @return \Pinenut\Model\Updater
	 */

	function modify() {
		$containerField = $this->_parent->getFullFieldName();
		$model = $this->getModel();
		// TODO: хреново сделано, т.к. используется монговская схема, надо абстрагироваться!
		return $this->getModel()
					->modify()
					->setDefaultField($containerField, true)
					->where('_ref', $model::typeCast($this->_ref, static::ID));
				  	
	}
	
	function __toString(){
		return (string)$this->_ref;
	}
	
	/**
	 * @return \Pinenut\Model|array
	 */
	function find($active = false) {
		$class = $this->_parent->getReferredClass();
		return $class::find($this->_ref, $active);
	}
	
}